﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JerrodSoft.Serialization.Xml.Xsd
{
    public class RootElement
    {
        public RootElement(){
            this.XmlNamespace = "xs";
        }

        public string XmlNamespace{get;set;}
        public string Name { get; set; }
        public bool IsComplexType { get; set; }

        public IEnumerable<ChildElement> Elements { get; set; }

        public override string ToString()
        {
            if (string.IsNullOrEmpty(Name))
                throw new NullReferenceException("Name cannot be null.");

            StringBuilder sb = new StringBuilder();
            sb.Append("<").Append(XmlNamespace).Append(@":element name=""").Append(this.Name).Append(@""">\n");
            sb.Append("<").Append(XmlNamespace).Append(@":complexType>\n");
            sb.Append("<").Append(XmlNamespace).Append(@":sequence>\n");

            if (this.Elements != null)
            {
                foreach (var element in this.Elements)
                {
                    if (element == null)
                        continue;
                    if (element.Type == null)
                        throw new Exception("Element type cannot be null.");
                    if (string.IsNullOrEmpty(element.Name))
                        throw new Exception("Element name must be set.");

                    bool isNullable = !element.Type.IsValueType || (Nullable.GetUnderlyingType(element.Type) != null);
                    string type = XsdSerializer.GetTypeName(element.Type);
                    sb.Append("<").Append(XmlNamespace).Append(@":element minOccurs=""").Append(element.MinimumOccurrences.ToString()).Append(@""" name=""").Append(element.Name).Append(@""" nillable=""").Append(isNullable.ToString()).Append(@""" type=""").Append(type).Append(@"""/>\n");
                }
            }

            sb.Append("</").Append(XmlNamespace).Append(":sequence>\n");
            sb.Append("</").Append(XmlNamespace).Append(":complexType>\n");
            sb.Append("</").Append(XmlNamespace).Append(":element>\n");

            return sb.ToString();
        }
    }

    public class ChildElement
    {
        public UInt32 MinimumOccurrences { get; set; }
        public string Name { get; set; }
        public Type Type { get; set; }
    }
}
